﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OthelloGame;
using OthelloCognition;
namespace OthelloConsole
{
    class Program
    {
        static string usage = @"usage: othellosim -w playerType -b playerType [-t time/turn in ms] [-g games] -o outputFile
            [-t] defaults to 10000 ms (10s)
            [-g] defaults to 1 game
            playerTypes are: " + solverNames();

        static void Main(string[] args)
        {
            // What are the command line arguments?
            // -w # type of white player
            // -b # type of black player
            // -t # time per turn
            // -o output file
            // -g # games
            
            if(args.Length == 0) {
                error("Not enough arguments");
            }

            AbstractSolver white = null, black = null;
            int turnTimeInMS = 10000, games = 1;
            StreamWriter results = null;

            for(int i = 0; i < args.Length; i++)
            {
                switch (args[i])
                {
                    case "-w":
                        i++;
                        try
                        {
                            white = NewSolver.NewSolverConstructor((SolverEnum)Enum.Parse(typeof(SolverEnum), args[i], true));
                        }
                        catch
                        {
                            error("Invalid white player type: \"" + args[i] + "\".  Valid types include:\n" + solverNames());
                        }
                        break;
                    case "-b":
                        i++;
                        try
                        {
                            black = NewSolver.NewSolverConstructor((SolverEnum)Enum.Parse(typeof(SolverEnum), args[i], true));
                        }
                        catch
                        {
                            error("Invalid black player type: \"" + args[i] + "\".  Valid types include:\n" + solverNames());
                        }
                        break;
                    case "-t":
                        i++;
                        try
                        {
                            turnTimeInMS = Convert.ToInt16(args[i]);
                        }
                        catch
                        {
                            error("Invalid number for turn time: \"" + args[i] + "\".");
                        }
                        break;
                    case "-g":
                        i++;
                        try
                        {
                            games = Convert.ToInt16(args[i]);
                        }
                        catch
                        {
                            error("Invalid number for number of games: \"" + args[i] + "\".");
                        }
                        break;
                    case "-o":
                        i++;
                        try
                        {
                            results = File.CreateText(args[i]);
                        }
                        catch
                        {
                            error("Bad output file: \"" + args[i] + "\"");
                        }
                        break;
                    default:
                        error("Bad argument: \"" + args[i] + "\"");
                        break;
                }
            }

            if (white == null || black == null || results == null)
            {
                error("Missing argument for white player, black player, or output file");
            }

            Console.WriteLine(@"Input values: white = " + white + ", black = " + black + ", turnTime = " + turnTimeInMS 
                + ", numGames = " + games + ", file = " + results);

            for (int i = 0; i < games; i++)
            {
                OthelloConsoleGame ocg = new OthelloConsoleGame(
                                            white,
                                            black,
                                            turnTimeInMS
                                         );
                ocg.playGame();
                writeResults(results, i + 1, ocg.GameResults, ocg.MoveHistory);
            }
            
            results.Close();
            Console.Write("Games complete, done with writing results");
            //Console.In.ReadLine();
        }

        public static void writeResults(StreamWriter output, int game, int[] scores, int[,] moves)
        {
            output.WriteLine("*** Game {0} ***", game);
            if (scores[0] > scores[1])
                output.Write("Black Win : ");
            else if (scores[0] < scores[1])
                output.Write("White Win : ");
            else
                output.Write("Tie : ");

            output.WriteLine("{0}, {1}", scores[0], scores[1]);

            int numMoves = scores[0] + scores[1] - 4;
            output.WriteLine(" -- Moves -- ");
            for (int i = 0; i < numMoves; i++)
            {
                output.WriteLine("Move " + (i + 1) + ": " + moves[i,0] + ", " + moves[i,1] + ", " + moves[i,2]);
            }
            output.WriteLine();
 //           Console.WriteLine("Done with writing results, numMoves = " + numMoves);
        }

        public static string solverNames()
        {
            string names = "";
            
            Type solverType = typeof(SolverEnum);
            foreach(string s in Enum.GetNames(solverType)) {
                names += s + ", " ;
            }

            return names;
        }

        private static void error(string err)
        {
            Console.WriteLine("ERROR: " + err);
            Console.Write(usage);
            //Console.In.ReadLine();
            Environment.Exit(1);
        }
    }
}
